# Copyright (c) 2025 Li Auto Inc. and its affiliates
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

include(CheckCXXSourceCompiles)

# Set source files

if(WIN32)
    file(GLOB_RECURSE ALL_HEADERS
        ${PROJECT_SOURCE_DIR}/include/**/*.h
        ${PROJECT_SOURCE_DIR}/include/**/*.hpp
        ${PROJECT_SOURCE_DIR}/src/cpp/**/*.h
        ${PROJECT_SOURCE_DIR}/src/cpp/**/*.hpp
        )

    add_definitions(-DNOMINMAX)
    list(APPEND UNIFIED_DEFINES "-DNOMINMAX")
endif(WIN32)

# if(SECURITY)
#     set(HAVE_SECURITY 1)
# else()
#     set(HAVE_SECURITY 0)
# endif()

file(GLOB DDSSQLFILTER_SOURCES
    rtps/content_filter/DDSSQLFilter/*.cpp
    rtps/content_filter/IContentFilterFactory.cpp)

set(DISCOVERY "discovery")
set(${PROJECT_NAME}_source_files
    ${ALL_HEADERS}
    ${DDSSQLFILTER_SOURCES}
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/writer/LivelinessManager.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/writer/LocatorSelectorSender.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/writer/RTPSWriter.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/writer/StatefulWriter.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/writer/ReaderProxy.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/writer/StatelessWriter.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/writer/ReaderLocator.cpp

    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/reader/WriterProxy.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/reader/StatefulReader.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/reader/StatelessReader.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/reader/RTPSReader.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/reader/reader_utils.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/messages/RTPSMessageCreator.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/messages/RTPSMessageGroup.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/messages/RTPSGapBuilder.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/messages/SendBuffersManager.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/messages/MessageReceiver.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/messages/submessages/AckNackMsg.hpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/messages/submessages/DataMsg.hpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/messages/submessages/GapMsg.hpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/messages/submessages/HeartbeatMsg.hpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/network/ExternalLocatorsProcessor.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/participant/RTPSParticipant.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/participant/RTPSParticipantImpl.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/RTPSDomain.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/common/DynamicPubSubType.cpp

    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/core/policy/ParameterList.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/builtin/lookup/common/LookupTypes.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/builtin/common/RPCHeadersImpl.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/builtin/lookup/LookupManager.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/builtin/lookup/LookupRequestListener.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/builtin/lookup/LookupReplyListener.cpp

    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/builtin/BuiltinProtocols.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/discovery/participant/DirectMessageSender.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/discovery/participant/PDP.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/discovery/participant/ServerAttributes.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/discovery/participant/PDPSimple.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/discovery/participant/PDPListener.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/discovery/participant/PDPClient.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/discovery/participant/PDPClientListener.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/discovery/participant/PDPServer.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/discovery/participant/PDPServerListener.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/discovery/participant/PDPServerCompatibleListener.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/discovery/monitoring/MonitorPid.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/discovery/endpoint/EDP.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/discovery/endpoint/EDPSimple.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/discovery/endpoint/EDPSimpleListeners.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/discovery/endpoint/EDPStatic.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/discovery/endpoint/EDPClient.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/discovery/endpoint/EDPServer.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/discovery/endpoint/EDPServerListeners.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/discovery/database/backup/SharedBackupFunctions.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/discovery/database/DiscoveryDataBase.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/discovery/database/DiscoveryParticipantInfo.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/discovery/database/DiscoveryParticipantsAckStatus.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/discovery/database/DiscoverySharedInfo.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/discovery/database/DiscoveryEndpointInfo.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/discovery/participant/DS/PDPSecurityInitiatorListener.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/discovery/participant/timedevent/DSClientEvent.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/discovery/participant/timedevent/DServerEvent.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/builtin/liveliness/WLP.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/builtin/liveliness/WLPListener.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/builtin/data/ParticipantProxyData.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/builtin/data/WriterProxyData.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/builtin/data/ReaderProxyData.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/flowcontrol/FlowControllerFactory.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/exceptions/Exception.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/common/Token.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/common/E2E_common.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/xmlparser/XMLAssignManager.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/xmlparser/XMLElementParser.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/xmlparser/XMLDynamicParser.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/xmlparser/XMLEndpointParser.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/xmlparser/XMLParser.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/xmlparser/XMLProfileManager.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/writer/PersistentWriter.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/writer/StatelessPersistentWriter.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/writer/StatefulPersistentWriter.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/reader/StatelessPersistentReader.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/reader/StatefulPersistentReader.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/persistence/PersistenceFactory.cpp

    ${CMAKE_CURRENT_SOURCE_DIR}/utils/StringMatching.cpp
    )


###############################################################################
# ELOG
###############################################################################
# Set source files
# option(BUILD_SHARED_LIBS "Create shared libraries by default" ON)
set(VBSLOG "elog")
set(${VBSLOG}_source_files
    ${PROJECT_SOURCE_DIR}/../utils/src/elog/Log.cpp
    ${PROJECT_SOURCE_DIR}/../utils/src/elog/OStreamConsumer.cpp
    ${PROJECT_SOURCE_DIR}/../utils/src/elog/StdoutErrConsumer.cpp
    ${PROJECT_SOURCE_DIR}/../utils/src/elog/StdoutConsumer.cpp
    ${PROJECT_SOURCE_DIR}/../utils/src/elog/FileConsumer.cpp
    ${PROJECT_SOURCE_DIR}/../utils/src/elog/ApiConsumer.cpp

    ${PROJECT_SOURCE_DIR}/../utils/src/elog/utils/System.cpp
    ${PROJECT_SOURCE_DIR}/../utils/src/elog/utils/SystemInfo.cpp
    ${PROJECT_SOURCE_DIR}/../utils/src/elog/utils/md5.cpp
    ${PROJECT_SOURCE_DIR}/../utils/src/elog/utils/IPFinder.cpp
    ${PROJECT_SOURCE_DIR}/../utils/src/elog/utils/IPLocator.cpp
    ${PROJECT_SOURCE_DIR}/../utils/src/deps/common/Time_t.cpp
    ${PROJECT_SOURCE_DIR}/../utils/src/deps/qos/BaseQosPolicy.cpp
)
if(EDDS_METRICS)
    list(APPEND ${VBSLOG}_source_files
        ${PROJECT_SOURCE_DIR}/../utils/src/elog/statistics/Statistics.cpp
        ${PROJECT_SOURCE_DIR}/../utils/src/elog/statistics/StatisticsImpl.cpp
        )
endif()

if(NOT ANDROID)
    find_package(Threads REQUIRED)
endif()

# Define public headers
configure_file(${PROJECT_SOURCE_DIR}/../utils/include/config.h.in
    ${PROJECT_BINARY_DIR}/../utils/include/utils/config.h
    @ONLY
    CONFIGURE_DEPENDS)

####
#XMLParser
# Set source files
option(BUILD_SHARED_LIBS "Create shared libraries by default" ON)
set(XMLParser "xmlparser")
set(${XMLParser}_source_files
    ${CMAKE_CURRENT_SOURCE_DIR}/xmlparser/XMLParserCommonPart.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/xmlparser/XMLElementParserPart.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/xmlparser/XMLParserPart.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/xmlparser/XMLProfileManagerPart.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/xmlparser/XMLEndpointParserPart.cpp

    ${CMAKE_CURRENT_SOURCE_DIR}/xmlparser/qos/XMLDataReaderQos.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/xmlparser/qos/XMLDataWriterQos.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/xmlparser/qos/XMLPublisherQos.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/xmlparser/qos/XMLReaderQos.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/xmlparser/qos/XMLSubscriberQos.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/xmlparser/qos/XMLTopicQos.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/xmlparser/qos/XMLWriterQos.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/xmlparser/qos/XMLPropertyPolicy.cpp

    ${CMAKE_CURRENT_SOURCE_DIR}/xmlparser/data/XMLReaderProxyData.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/xmlparser/data/XMLWriterProxyData.cpp
)
if(NOT ANDROID)
    find_package(Threads REQUIRED)
endif()

#SQLITE3 persistence service sources
set(${PROJECT_NAME}_sqlite3_source_files
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/persistence/SQLite3PersistenceService.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/persistence/sqlite3.c
    )

if(SQLITE3_SUPPORT)
    list(APPEND ${PROJECT_NAME}_source_files
        ${${PROJECT_NAME}_sqlite3_source_files}
        )
endif()

set(COMMON "common")
set(${COMMON}_source_files
    ${PROJECT_SOURCE_DIR}/../utils/src/history/CacheChangePool.cpp
    ${PROJECT_SOURCE_DIR}/../utils/src/history/History.cpp
    ${PROJECT_SOURCE_DIR}/../utils/src/history/WriterHistory.cpp
    ${PROJECT_SOURCE_DIR}/../utils/src/history/ReaderHistory.cpp
    ${PROJECT_SOURCE_DIR}/../utils/src/history/TopicPayloadPool.cpp
    ${PROJECT_SOURCE_DIR}/../utils/src/history/TopicPayloadPoolRegistry.cpp
    ${PROJECT_SOURCE_DIR}/../utils/src/deps/resources/TimedEvent.cpp
    ${PROJECT_SOURCE_DIR}/../utils/src/deps/resources/TimedEventImpl.cpp
    ${PROJECT_SOURCE_DIR}/../utils/src/deps/resources/ResourceEvent.cpp
    ${PROJECT_SOURCE_DIR}/../utils/src/deps/dynamic-types/TypeDescriptor.cpp
    ${PROJECT_SOURCE_DIR}/../utils/src/deps/dynamic-types/TypeIdentifier.cpp
    ${PROJECT_SOURCE_DIR}/../utils/src/deps/dynamic-types/TypeIdentifierTypes.cpp
    ${PROJECT_SOURCE_DIR}/../utils/src/deps/dynamic-types/TypeObject.cpp
    ${PROJECT_SOURCE_DIR}/../utils/src/deps/dynamic-types/TypeObjectHashId.cpp
    ${PROJECT_SOURCE_DIR}/../utils/src/deps/dynamic-types/TypeObjectFactory.cpp
    ${PROJECT_SOURCE_DIR}/../utils/src/deps/dynamic-types/TypeNamesGenerator.cpp
    ${PROJECT_SOURCE_DIR}/../utils/src/deps/dynamic-types/TypesBase.cpp
    ${PROJECT_SOURCE_DIR}/../utils/src/deps/dynamic-types/BuiltinAnnotationsTypeObject.cpp
    ${PROJECT_SOURCE_DIR}/../utils/src/deps/dynamic-types/DynamicDataHelper.cpp
    ${PROJECT_SOURCE_DIR}/../utils/src/deps/dynamic-types/DynamicDataPrinter.cpp
    ${PROJECT_SOURCE_DIR}/../utils/src/deps/dynamic-types/AnnotationDescriptor.cpp
    ${PROJECT_SOURCE_DIR}/../utils/src/deps/dynamic-types/AnnotationParameterValue.cpp
    ${PROJECT_SOURCE_DIR}/../utils/src/deps/dynamic-types/DynamicData.cpp
    ${PROJECT_SOURCE_DIR}/../utils/src/deps/dynamic-types/DynamicUnionData.cpp
    ${PROJECT_SOURCE_DIR}/../utils/src/deps/dynamic-types/DynamicMapData.cpp
    ${PROJECT_SOURCE_DIR}/../utils/src/deps/dynamic-types/DynamicDataMemPool.cpp
    ${PROJECT_SOURCE_DIR}/../utils/src/deps/dynamic-types/DynamicSequenceData.cpp
    ${PROJECT_SOURCE_DIR}/../utils/src/deps/dynamic-types/DynamicDataFactory.cpp
    ${PROJECT_SOURCE_DIR}/../utils/src/deps/dynamic-types/DynamicType.cpp
    ${PROJECT_SOURCE_DIR}/../utils/src/deps/dynamic-types/DynamicTypePtr.cpp
    ${PROJECT_SOURCE_DIR}/../utils/src/deps/dynamic-types/DynamicDataPtr.cpp
    ${PROJECT_SOURCE_DIR}/../utils/src/deps/dynamic-types/DynamicTypeBuilder.cpp
    ${PROJECT_SOURCE_DIR}/../utils/src/deps/dynamic-types/DynamicTypeBuilderPtr.cpp
    ${PROJECT_SOURCE_DIR}/../utils/src/deps/dynamic-types/DynamicTypeBuilderFactory.cpp
    ${PROJECT_SOURCE_DIR}/../utils/src/deps/dynamic-types/DynamicTypeMember.cpp
    ${PROJECT_SOURCE_DIR}/../utils/src/deps/dynamic-types/MemberDescriptor.cpp
    ${PROJECT_SOURCE_DIR}/../utils/src/deps/common/string_convert.cpp
    ${PROJECT_SOURCE_DIR}/../utils/src/deps/common/TimedConditionVariable.cpp
)

# Generate the proper configure file
configure_file(${PROJECT_SOURCE_DIR}/include/${XMLParser}/config.h.in
    ${PROJECT_BINARY_DIR}/include/${XMLParser}/config.h
    @ONLY
    CONFIGURE_DEPENDS)

# Security sources
set(${PROJECT_NAME}_security_source_files
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/security/exceptions/SecurityException.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/security/common/SharedSecretHandle.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/security/common/AuthToken.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/security/logging/Logging.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/security/SecurityManager.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/rtps/security/SecurityPluginFactory.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/discovery/participant/DS/PDPSecurityInitiatorListener.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/security/authentication/PKIDH.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/security/accesscontrol/Permissions.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/security/cryptography/AESGCMGMAC.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/security/cryptography/AESGCMGMAC_KeyExchange.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/security/cryptography/AESGCMGMAC_KeyFactory.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/security/cryptography/AESGCMGMAC_Transform.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/security/cryptography/AESGCMGMAC_Types.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/security/authentication/PKIIdentityHandle.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/security/authentication/PKIHandshakeHandle.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/security/accesscontrol/AccessPermissionsHandle.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/security/accesscontrol/CommonParser.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/security/accesscontrol/GovernanceParser.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/security/accesscontrol/PermissionsParser.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/security/logging/LogTopic.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/security/artifact_providers/FileProvider.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/security/artifact_providers/Pkcs11Provider.cpp
    # E2E
    #${CMAKE_CURRENT_SOURCE_DIR}/security/e2e/src/buffer/buffer.cpp
    #${CMAKE_CURRENT_SOURCE_DIR}/security/e2e/src/crc/crc.cpp
    #${CMAKE_CURRENT_SOURCE_DIR}/security/e2e/src/profile/profile04/checker.cpp
    #${CMAKE_CURRENT_SOURCE_DIR}/security/e2e/src/profile/profile04/profile_04.cpp
    #${CMAKE_CURRENT_SOURCE_DIR}/security/e2e/src/profile/profile04/protector.cpp
    )

if(SECURITY)
    list(APPEND ${PROJECT_NAME}_source_files
        ${${PROJECT_NAME}_security_source_files}
        )
endif()

if(VBSAUTH)
    set(VBSAUTH 1)
    add_definitions(-DVBSAUTH)
    list(APPEND UNIFIED_DEFINES "-DVBSAUTH")
else()
    set(VBSAUTH 0)
endif()

if(WIN32 AND (MSVC OR MSVC_IDE))
    list(APPEND ${PROJECT_NAME}_source_files
        ${PROJECT_SOURCE_DIR}/src/cpp/ertps.rc
        )
endif()

# External sources
if(TINYXML2_SOURCE_DIR)
    set(TINYXML2_SOURCE_DIR_ ${TINYXML2_SOURCE_DIR})
    list(APPEND ${PROJECT_NAME}_source_files
        ${TINYXML2_SOURCE_DIR_}/tinyxml2.cpp
        )
endif()

if(ANDROID)
    if((ANDROID_PLATFORM LESS_EQUAL 23) OR (ANDROID_NATIVE_API_LEVEL LESS_EQUAL 23))
        list(APPEND ${PROJECT_NAME}_source_files
            ${ANDROID_IFADDRS_SOURCE_DIR}/ifaddrs.c
            )
    endif()
endif()


if(NOT ANDROID)
    find_package(Threads REQUIRED)
endif()

# Find out if libatomic link is required in this platform
find_package(Atomic MODULE)

# Generate the proper configure file
configure_file(${PROJECT_SOURCE_DIR}/include/${PROJECT_NAME}/config.h.in
    ${PROJECT_BINARY_DIR}/include/${PROJECT_NAME}/config.h
    @ONLY
    CONFIGURE_DEPENDS)

add_subdirectory(transport EXCLUDE_FROM_ALL)

###############################################################################
# Packaging
###############################################################################
# Install public headers
install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/${PROJECT_NAME}
    DESTINATION ${INCLUDE_INSTALL_DIR}
    COMPONENT headers
    FILES_MATCHING
    PATTERN "*.h"
    PATTERN "*.hpp"
    PATTERN "*.ipp"
    )

# Install config.h header
install(FILES ${PROJECT_BINARY_DIR}/include/${PROJECT_NAME}/config.h
    DESTINATION ${INCLUDE_INSTALL_DIR}/${PROJECT_NAME}
    COMPONENT headers
    )

install(DIRECTORY ${PROJECT_SOURCE_DIR}/../utils/include/
    DESTINATION ${INCLUDE_INSTALL_DIR}/
    COMPONENT headers
    )

install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/${XMLParser}/
    DESTINATION ${INCLUDE_INSTALL_DIR}/${XMLParser}
    COMPONENT headers
    )

install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/${DISCOVERY}/
    DESTINATION ${INCLUDE_INSTALL_DIR}/${DISCOVERY}
    COMPONENT headers
    )

install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/edds
    DESTINATION ${INCLUDE_INSTALL_DIR}
    COMPONENT headers
    FILES_MATCHING
    PATTERN "*.h"
    PATTERN "*.hpp"
    PATTERN "*.ipp"
    )

# Install config.h headers
install(FILES ${PROJECT_BINARY_DIR}/include/${XMLParser}/config.h
    DESTINATION ${INCLUDE_INSTALL_DIR}/${XMLParser}
    COMPONENT headers
    )

set(CPACK_COMPONENT_HEADERS_DISPLAY_NAME "C++ Headers" PARENT_SCOPE)
set(CPACK_COMPONENT_HEADERS_DESCRIPTION "EVBS C++ Headers" PARENT_SCOPE)

if(MSVC OR MSVC_IDE)
    # Install pdb files
    install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/Debug/
        DESTINATION ${LIB_INSTALL_DIR}
        COMPONENT libraries
        CONFIGURATIONS Debug
        FILES_MATCHING
        PATTERN "*.pdb"
        )
endif()


# # Install libraries
# # Generate different target names depending on linking
# get_target_property(TARGET_TYPE ${PROJECT_NAME} TYPE)
# if(TARGET_TYPE STREQUAL "SHARED_LIBRARY")
#     set(EDDS_LINKING dynamic)
# else()
#     set(EDDS_LINKING static)
# endif()

# install(TARGETS ${PROJECT_NAME} vbs_atomic
#     EXPORT ${PROJECT_NAME}-${EDDS_LINKING}-targets
#     COMPONENT libraries
#     RUNTIME DESTINATION "${BIN_INSTALL_DIR}${MSVCARCH_DIR_EXTENSION}"
#     LIBRARY DESTINATION "${LIB_INSTALL_DIR}${MSVCARCH_DIR_EXTENSION}"
#     ARCHIVE DESTINATION "${LIB_INSTALL_DIR}${MSVCARCH_DIR_EXTENSION}"
#     )

# if (CONAN_INSTALL)
#     if(BUILD_UNIFIED_LIB)
#         export(TARGETS ${PROJECT_NAME} vbs_atomic FILE ${PROJECT_BINARY_DIR}/cmake/config/${PROJECT_NAME}-${EDDS_LINKING}-targets.cmake)
#     else()
#         export(TARGETS ${PROJECT_NAME} vbs_atomic FILE ${PROJECT_BINARY_DIR}/cmake/config/${PROJECT_NAME}-${EDDS_LINKING}-targets.cmake)
#     endif()
# else()
#     export(TARGETS ${PROJECT_NAME} vbs_atomic FILE ${PROJECT_BINARY_DIR}/cmake/config/${PROJECT_NAME}-${EDDS_LINKING}-targets.cmake)
# endif()



# if(NOT CONAN_INSTALL)
#     if(INSTALLER_PLATFORM)
#         set(INSTALL_DESTINATION_PATH ${DATA_INSTALL_DIR}/${PROJECT_NAME}-${INSTALLER_PLATFORM}/cmake)
#     else()
#         set(INSTALL_DESTINATION_PATH ${DATA_INSTALL_DIR}/${PROJECT_NAME}/cmake${MSVCARCH_DIR_EXTENSION_EXT})
#     endif()

#     install(EXPORT ${PROJECT_NAME}-${EDDS_LINKING}-targets
#         DESTINATION ${INSTALL_DESTINATION_PATH}
#         COMPONENT cmake
#         )

#     if(WIN32 OR MSVC OR MSVC_IDE)

#         # first try dll symbols
#         get_target_property(PDB_FILE ${PROJECT_NAME} PDB_NAME_DEBUG)
#         if(PDB_FILE)
#             get_target_property(PDB_DIR ${PROJECT_NAME} PDB_OUTPUT_DIRECTORY_DEBUG)
#             set(PDB_FILE "${PDB_DIR}/${PDB_FILE}.pdb")
#         else()
#             # fallback to static lib symbols
#             get_target_property(PDB_FILE ${PROJECT_NAME} COMPILE_PDB_NAME_DEBUG)
#             if(PDB_FILE)
#                 get_target_property(PDB_DIR ${PROJECT_NAME} COMPILE_PDB_OUTPUT_DIRECTORY_DEBUG)
#                 set(PDB_FILE "${PDB_DIR}/${PDB_FILE}.pdb")
#             endif()
#         endif()

#         # install symbols if any
#         if(PDB_FILE)
#             install(FILES ${PDB_FILE}
#                 DESTINATION ${LIB_INSTALL_DIR}${MSVCARCH_DIR_EXTENSION}
#                 COMPONENT symbols
#                 CONFIGURATIONS Debug
#                 )
#         endif()
#     endif()

#     ###############################################################################
#     # Create CMake package config file
#     ###############################################################################
#     include(CMakePackageConfigHelpers)

#     if(BUILD_SHARED_LIBS)
#         set(ERTPS_PACKAGE_OPT_BIN_DIR_CONDITION "if(MSVC OR MSVC_IDE)")
#     else()
#         set(ERTPS_PACKAGE_OPT_BIN_DIR_CONDITION "if(0)")
#     endif()

#     # include the option parser targets
#     set(INCLUDE_EDDS_ENTITYTARGETS "include(\${CMAKE_CURRENT_LIST_DIR}/optionparser-targets.cmake)")

#     if(COMPILE_TOOLS)
#         # include the fast-discovery-server targets (not for linking but to hint binaries location and other target properties)
#         # If you want to include fast-discovery-server-targets.cmake, open tools/CMakeLists.txt/add_subdirectory(fds), vice versa.
#         #set(INCLUDE_EDDS_ENTITYTARGETS "${INCLUDE_EDDS_ENTITYTARGETS}\ninclude(\${CMAKE_CURRENT_LIST_DIR}/fast-discovery-server-targets.cmake)")
#     endif()

#     # Add ertps dependencies in its CMake config file.
#     if(LINK_SSL)
#         if(INSTALLER_PLATFORM)
#             # OpenSSL dependency is only propagated on static linking
#             # We must use the deployed OpenSSL binaries to prevent compatibility issues
#             set(ERTPS_INSTALLER_DEPS_ANCILLARY "\
#             function(find_edds_deployed_openssl)\n\
#                 if(OPENSSL_FOUND AND NOT(OPENSSL_VERSION STREQUAL \"${OPENSSL_VERSION}\") )\n\
#                     message(WARNING \"OpenSSL already loaded. Version \${OPENSSL_VERSION} differs from version ${OPENSSL_VERSION}, used in EDDS binaries building, ABI issues may arise\")\n\
#                 endif()\n\
#                 set(OPENSSL_USE_STATIC_LIBS TRUE)\n\
#                 set(OPENSSL_ROOT_DIR  \"\${PACKAGE_PREFIX_DIR}/lib/${INSTALLER_PLATFORM}\")\n\
#                 find_package(OpenSSL REQUIRED)\n\
#             endfunction()"
#             )
#             set(ERTPS_INSTALLER_OPT_DEPS "find_edds_deployed_openssl()")
#         elseif(WIN32)
#             # windows from sources only requires OpenSSL on static libraries
#             set(ERTPS_PACKAGE_WIN32_OPT_DEPS "find_package(OpenSSL REQUIRED)")
#         else()
#             # linux from sources requires OpenSSL always
#             set(ERTPS_PACKAGE_UNIX_OPT_DEPS "find_package(OpenSSL REQUIRED)")
#         endif()
#     endif()

#     configure_package_config_file(${PROJECT_SOURCE_DIR}/cmake/packaging/Config.cmake.in
#         ${PROJECT_BINARY_DIR}/cmake/config/${PROJECT_NAME}-config.cmake
#         INSTALL_DESTINATION ${INSTALL_DESTINATION_PATH}
#         PATH_VARS BIN_INSTALL_DIR INCLUDE_INSTALL_DIR LIB_INSTALL_DIR
#         )
#     if (NOT ANDROID)
#         write_basic_package_version_file(${PROJECT_BINARY_DIR}/cmake/config/${PROJECT_NAME}-config-version.cmake
#             VERSION ${PROJECT_VERSION}
#             COMPATIBILITY SameMajorVersion
#             )
#         install(FILES ${PROJECT_BINARY_DIR}/cmake/config/${PROJECT_NAME}-config.cmake
#             ${PROJECT_BINARY_DIR}/cmake/config/${PROJECT_NAME}-config-version.cmake
#             DESTINATION ${INSTALL_DESTINATION_PATH}
#             COMPONENT cmake
#             )
#     endif()
#         set(CPACK_COMPONENT_LIBRARIES_DISPLAY_NAME "Libraries" PARENT_SCOPE)
#         set(CPACK_COMPONENT_LIBRARIES_DESCRIPTION "EVBS libraries" PARENT_SCOPE)

#         configure_package_config_file(${PROJECT_SOURCE_DIR}/cmake/packaging/ElogConfig.cmake.in
#             ${CMAKE_CURRENT_BINARY_DIR}/${VBSLOG}-config.cmake
#             INSTALL_DESTINATION ${LIB_INSTALL_DIR}/cmake/${VBSLOG}
#             PATH_VARS BIN_INSTALL_DIR INCLUDE_INSTALL_DIR LIB_INSTALL_DIR
#             )
#     if (NOT ANDROID)
#         write_basic_package_version_file(
#             ${CMAKE_CURRENT_BINARY_DIR}/${VBSLOG}-config-version.cmake
#             VERSION ${PROJECT_VERSION}
#             COMPATIBILITY SameMajorVersion
#             )
#         install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${VBSLOG}-config.cmake
#             ${CMAKE_CURRENT_BINARY_DIR}/${VBSLOG}-config-version.cmake
#             DESTINATION ${LIB_INSTALL_DIR}/cmake/${VBSLOG}
#             COMPONENT cmake
#             )
#     endif()
# endif()

###############################################################################
# Add unified library support
###############################################################################
if(BUILD_UNIFIED_LIB)
    # 将所有源文件添加到统一库的源文件列表中
    list(APPEND UNIFIED_SOURCES
        ${${PROJECT_NAME}_source_files}
        ${${XMLParser}_source_files}
        ${${VBSRPC}_source_files}
    )

    # 将包含目录添加到统一库的包含目录列表中
    list(APPEND UNIFIED_INCLUDE_DIRS
        ${PROJECT_SOURCE_DIR}/include
        ${PROJECT_BINARY_DIR}/include
        ${PROJECT_BINARY_DIR}/include/${PROJECT_NAME}
        ${PROJECT_SOURCE_DIR}/src/cpp
        ${Asio_INCLUDE_DIR}
        ${TINYXML2_INCLUDE_DIR}
        ${ANDROID_IFADDRS_INCLUDE_DIR}
        # ${THIRDPARTY_BOOST_INCLUDE_DIR}
        ${PROJECT_SOURCE_DIR}/../thirdparty/taocpp-pegtl
        ${CONAN_INCLUDE_DIRS}
        ${PROJECT_SOURCE_DIR}/../utils/include
        ${ECDR_INCLUDE_PATH}
        ${PROJECT_SOURCE_DIR}/../utils/include
        ${PROJECT_BINARY_DIR}/../utils/include
        ${RPC_INCLUDE_DIR}
        ${RPC_INCLUDE_DIR}/${VBSRPC}
        ${RPC_SRC_DIR}
        ${PROJECT_SOURCE_DIR}/../framework/vmw/include/
    )

    if(NOT CONAN_BUILD)
        list(APPEND UNIFIED_INCLUDE_DIRS
            ${LIDDSAUTH_DIR}/include
        )
    endif()

    list(APPEND UNIFIED_INCLUDE_DIRS_PRIVATE
        ${THIRDPARTY_BOOST_INCLUDE_DIR}
    )

    if (MINGW64)
        # 将链接库添加到统一库的链接库列表中
        list(APPEND UNIFIED_LINK_LIBS
            ws2_32
            mswsock
            ${ecdr}
            foonathan_memory
            ${CMAKE_THREAD_LIBS_INIT}
            ${CMAKE_DL_LIBS}
            tinyxml2
            $<$<BOOL:${LINK_SSL}>:OpenSSL::SSL$<SEMICOLON>OpenSSL::Crypto$<$<BOOL:${WIN32}>:$<SEMICOLON>crypt32.lib>>
            $<$<BOOL:${WIN32}>:iphlpapi$<SEMICOLON>Shlwapi>
            ${THIRDPARTY_BOOST_LINK_LIBS}
            vbs_atomic
        )

        if(LINK_SSL)
            list(APPEND UNIFIED_LINK_LIBS OpenSSL::SSL OpenSSL::Crypto)
            if(WIN32)
                list(APPEND UNIFIED_LINK_LIBS crypt32)
            endif()
        endif()

        if(WIN32)
            list(APPEND UNIFIED_LINK_LIBS iphlpapi Shlwapi)
        endif()
    else()
        list(APPEND UNIFIED_LINK_LIBS
            ecdr
            foonathan_memory
            ${CMAKE_THREAD_LIBS_INIT}
            ${CMAKE_DL_LIBS}
            ${TINYXML2_LIBRARY}
            ${THIRDPARTY_BOOST_LINK_LIBS}
            vbs_atomic
        )

        if(LINK_SSL)
            list(APPEND UNIFIED_LINK_LIBS OpenSSL::SSL OpenSSL::Crypto)
            if(WIN32)
                list(APPEND UNIFIED_LINK_LIBS crypt32)
            endif()
        endif()

        if(WIN32)
            list(APPEND UNIFIED_LINK_LIBS iphlpapi Shlwapi)
        endif()

        if(VBSAUTH AND CONAN_BUILD)
            list(APPEND UNIFIED_LINK_LIBS vbsauth)
            if(CONAN_PLATFORM STREQUAL "schu")
                list(APPEND UNIFIED_LINK_LIBS veh_pki)
            endif()
        endif()
    endif()

    list(APPEND UNIFIED_DEFINES_PRIVATE
        BOOST_BIND_GLOBAL_PLACEHOLDERS
    )

    # 将变量传递回父作用域
    set(UNIFIED_SOURCES ${UNIFIED_SOURCES} CACHE INTERNAL "Unified sources for all libraries")
    set(UNIFIED_INCLUDE_DIRS ${UNIFIED_INCLUDE_DIRS} CACHE INTERNAL "Unified include directories for all libraries")
    set(UNIFIED_INCLUDE_DIRS_PRIVATE ${UNIFIED_INCLUDE_DIRS_PRIVATE} CACHE INTERNAL "Unified include directories for all libraries")
    set(UNIFIED_LINK_LIBS ${UNIFIED_LINK_LIBS} CACHE INTERNAL "Unified link libraries for all libraries")
    set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} CACHE INTERNAL "Unified cxx flags for all libraries")
    set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} CACHE INTERNAL "Unified c flags for all libraries")
    set(UNIFIED_DEFINES ${UNIFIED_DEFINES} CACHE INTERNAL "Unified defines for all libraries")
    set(UNIFIED_DEFINES_PRIVATE ${UNIFIED_DEFINES_PRIVATE} CACHE INTERNAL "Unified defines for all libraries")
endif()
